package com.kitty.game.task.service;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.achieve.common.SendAchieve;
import com.kitty.game.activity.service.task.TaskActivityHandler;
import com.kitty.game.activity.service.task.TowerTaskHandler;
import com.kitty.game.bag.message.RespIconCartoon;
import com.kitty.game.confirm.model.GiveUpTaskConfirm;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.enter.RespNotifyMisc;
import com.kitty.game.enter.RespUpdate;
import com.kitty.game.enter.TitleInfo;
import com.kitty.game.equip.EquipDataPool;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.map.service.MapService;
import com.kitty.game.npc.message.RespPlayInstruction;
import com.kitty.game.npc.service.NewNpcService;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.school.SchoolDataPool;
import com.kitty.game.school.service.SchoolService;
import com.kitty.game.talk.service.TalkService;
import com.kitty.game.task.TaskDataPool;
import com.kitty.game.task.message.RespTasks;
import com.kitty.game.task.message.RespTasksDel;
import com.kitty.game.task.message.vo.TaskInfo;
import com.kitty.game.task.model.product.targetparam.TalkTargetParam;
import com.kitty.game.task.model.user.RoleTask;
import com.kitty.game.task.service.targetHandler.TalkTargetHandler;
import com.kitty.game.task.service.targetHandler.TaskTargetHandler;
import com.kitty.game.task.service.targetHandler.TaskTargetHelper;
import com.kitty.game.task.service.taskHandler.*;
import com.kitty.game.team.message.RespConfirm;
import com.kitty.game.team.service.TeamService;
import com.kitty.game.utils.AsktaoUtil;
import com.kitty.game.utils.Const;
import com.kitty.listener.EventType;
import com.kitty.listener.annotation.EventHandler;
import com.kitty.mina.message.Message;
import com.kitty.mina.message.MessagePusher;
import com.kitty.mina.task.ThreadLocalUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import com.kitty.game.config.Equip;
import com.kitty.game.config.Instruction;
import com.kitty.game.config.NPC;
import com.kitty.game.config.TalkSet;
import com.kitty.game.config.TaskSet;
import com.kitty.game.task.model.product.TaskTarget;
import com.kitty.game.task.model.product.TaskTarget4Json;
import com.kitty.game.task.model.product.TaskTargetExecType;
import com.kitty.game.task.model.product.TaskTargetPopType;
import com.kitty.game.task.model.product.TaskTargetType;
import com.kitty.game.task.model.product.TaskType;
import com.kitty.game.task.service.taskHandler.DigTreasureTaskHandler;
import com.kitty.game.task.service.taskHandler.HelpPeopleTaskHandler;
import com.kitty.game.task.service.taskHandler.PetFlyTaskHandler;
import com.kitty.game.task.service.taskHandler.SchoolTaskHandler;
import com.kitty.game.task.service.taskHandler.TaskHandler;
import com.kitty.game.task.service.taskHandler.TaskHelper;
import com.kitty.listener.event.CallGuardEvent;
import com.kitty.listener.event.ConfirmEvent;
import com.kitty.listener.event.EnterMapEvent;
import com.kitty.listener.event.FetchEvent;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.listener.event.GatherEndEvent;
import com.kitty.listener.event.LoginEvent;
import com.kitty.listener.event.LogoutEvent;
import com.kitty.listener.event.MoveEvent;
import com.kitty.listener.event.OnEquipEvent;
import com.kitty.listener.event.RoleLevelUpEvent;
import com.kitty.listener.event.StudySkillEvent;
import com.kitty.listener.event.TalkEndEvent;
import com.kitty.listener.event.TaskEndEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@Service
public class NewTaskService {
    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    TalkService talkService;
    @Autowired
    RoleService roleService;
    @Autowired
    Dao dao;

    /**
     * 获得任务产品数据
     *
     * @param taskId
     * @return
     */
    public TaskSet getTaskSet(int taskId, Role role) {
        Map<Byte, TaskSet> setMap = TaskDataPool.taskMapBySchool.get(taskId);
        return (setMap != null ? setMap.get((byte) role.getPolar()) : null);
    }

    /**
     * 初始化指引数据
     */
    public void initInstruction() {
        Map<Byte, Map<Integer, Set<Instruction>>> typeToInstruction = new HashMap<>();
        List<Instruction> instructions = dao.query(Instruction.class, Cnd.NEW());
        instructions.forEach(instruction -> {
            Map<Integer, Set<Instruction>> reqToInstruction = typeToInstruction.computeIfAbsent(instruction.getType(), k -> new HashMap<>());
            Set<Instruction> set = reqToInstruction.computeIfAbsent(instruction.getReq(), k -> new HashSet<>());
            set.add(instruction);
            reqToInstruction.put(instruction.getReq(), set);
        });
        TaskDataPool.typeToInstruction = typeToInstruction;
    }

    /**
     * 获得任务产品数据
     *
     * @param taskId
     * @return
     */
    public TaskSet getTaskSet(int taskId, byte school) {
        Map<Byte, TaskSet> setMap = TaskDataPool.taskMapBySchool.get(taskId);
        return (setMap != null ? setMap.get(school) : null);
    }

    /**
     * 从数据库加载任务产品数据
     */
    public void loadTaskSet() {
        Map<Integer, TaskSet> taskMap = new HashMap<>();
        List<TaskSet> list = dao.query(TaskSet.class, Cnd.NEW());
        for (TaskSet taskSet : list) {
            initTaskTarget(taskSet);

            taskMap.put(taskSet.getId(), taskSet);
        }
        initialize(taskMap);

        Map<Integer, Map<Byte, TaskSet>> taskMapBySchool = newTaskMapBySchool(list);
        Map<Integer, Integer> talkToTaskMap = newTalkToTaskMap(list);
        Map<TaskType, List<Integer>> taskListByType = newTaskTypeListMap(list);

        TaskDataPool.taskMapBySchool = taskMapBySchool;
        TaskDataPool.talkToTaskMap = talkToTaskMap;
        TaskDataPool.taskListByType = taskListByType;
    }

    /**
     * 从传入map中获得对应数据
     */
    public void loadCommonSet(Map<String, String> commonSetMap) {
        String value = commonSetMap.get("help_people_taskids");
        if (value != null) {
            Map<String, String> map = Json.fromJson(Map.class, value);
            Map<String, Integer> helpTaskByName = new HashMap<>(map.size());
            for (Map.Entry<String, String> entry : map.entrySet()) {
                helpTaskByName.put(entry.getKey(), Integer.parseInt(entry.getValue()));
            }

            TaskDataPool.helpTaskByName = helpTaskByName;
        }
        value = commonSetMap.get("study_skill_task_id");
        if (value != null) {
            TaskDataPool.studySkillTaskId = Integer.parseInt(value.trim());
        }
    }


    private Map<Integer, Map<Byte, TaskSet>> newTaskMapBySchool(List<TaskSet> list) {
        SchoolService schoolService = SpringUtils.getBean(SchoolService.class);
        /**需要先初始化门派数据*/
        if (SchoolDataPool.schoolMap == null) {
            schoolService.loadSchoolSet();
        }

        Map<Integer, Map<Byte, TaskSet>> taskMapBySchool = new HashMap<>(list.size());
        Set<Byte> schoolSet = SchoolDataPool.schoolMap.keySet();

        TaskSet tempTaskSet = null;
        for (TaskSet taskSet : list) {
            tempTaskSet = taskSet;

            Map<Byte, TaskSet> setMap = new HashMap<>(schoolSet.size());
            taskMapBySchool.put(taskSet.getId(), setMap);

            /**处理门派相关的，任务介绍，任务指引，任务NPC名字*/
            for (Byte school : schoolSet) {
                String tempJieshao = schoolService.replaceSchoolDesc(school, taskSet.getTaskJieshao());
                String tempZhiyin = schoolService.replaceSchoolDesc(school, taskSet.getTaskZhiyin());
                String tempNpcName = schoolService.replaceSchoolDesc(school, taskSet.getNpcName());

                if (!tempJieshao.equals(taskSet.getTaskJieshao()) || !tempZhiyin.equals(taskSet.getTaskZhiyin()) || !tempNpcName.equals(taskSet.getNpcName())) {
                    try {
                        /**浅拷贝*/
                        tempTaskSet = taskSet.clone();
                    } catch (CloneNotSupportedException e) {
                        throw new RuntimeException("clone任务配置时出现异常" + e.getMessage(), e);
                    }

                    tempTaskSet.setTaskJieshao(tempJieshao);
                    tempTaskSet.setTaskZhiyin(tempZhiyin);
                    tempTaskSet.setNpcName(tempNpcName);


                    int taskTargetCount = taskSet.getTaskTargetCount();
                    for (int i = 0; i < taskTargetCount; i++) {
                        TaskTarget taskTarget = taskSet.getTaskTargetByIndex(i);
                        if (isMatchPopType(taskTarget, TaskTargetPopType.WALK_TO)) {

                            NutMap popParam = (NutMap) taskTarget.getPopParam();
                            boolean isMatchSchool = popParam.getBoolean("match_school", false);
                            if (isMatchSchool) {
                                /**本来想序列化实现深拷贝的，但是任务目标中的参数是个抽象类，无法创建类。貌似只能这样处理*/
                                copyTaskTarget(tempTaskSet);

                                NutMap positions = popParam.getAs("positions", NutMap.class);
                                NutMap position = positions.getAs(String.valueOf(school), NutMap.class);
                                tempTaskSet.getTaskTargetByIndex(i).setPopParam(position);

                                /**替换指引里的{x}和{y}*/
                                tempTaskSet.setTaskZhiyin(tempTaskSet.getTaskZhiyin().replace("{x}", String.valueOf(position.get("x"))).replace("{y}", String.valueOf(position.get("y"))));
                            }
                        }
                    }
                }

                setMap.put(school, tempTaskSet);
            }
        }

        return taskMapBySchool;
    }

    /**
     * 浅拷贝任务目标
     */
    private void copyTaskTarget(TaskSet taskSet) {
        int taskTargetCount = taskSet.getTaskTargetCount();
        List<TaskTarget> newTaskTargetList = new ArrayList<>(taskTargetCount);

        for (int i = 0; i < taskTargetCount; i++) {
            TaskTarget taskTarget = taskSet.getTaskTargetByIndex(i);
            try {
                newTaskTargetList.add(taskTarget.clone());
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException("clone任务目标时出现异常" + e.getMessage(), e);
            }
        }

        taskSet.setTaskTargetList(newTaskTargetList);
    }


    /**
     * 对任务进行一此初始化操作
     *
     * @param taskMap
     */
    private void initialize(Map<Integer, TaskSet> taskMap) {
        initPrevTask(taskMap);
    }

    /**
     * 初始化任务的任务目标
     */
    private void initTaskTarget(TaskSet taskSet) {
        try {
            List<TaskTarget4Json> taskTarget4JsonList = Json.fromJsonAsList(TaskTarget4Json.class, taskSet.getTaskTargetJson());
            if (taskTarget4JsonList == null) {
                taskSet.setTaskTargetList(new ArrayList<TaskTarget>(2));
            } else {
                List<TaskTarget> taskTargetList = new ArrayList<TaskTarget>(taskTarget4JsonList.size());
                for (TaskTarget4Json taskTarget4Json : taskTarget4JsonList) {
                    TaskTargetHandler taskTargetHandler = TaskTargetHelper.INSTANCE.getTargetHandler(taskTarget4Json.getTaskTargetType());
                    Class paramClass = TaskTargetHelper.INSTANCE.getTargetParamClass(taskTarget4Json.getTaskTargetType());

                    TaskTarget taskTarget = taskTargetHandler.createTarget(paramClass, taskTarget4Json);
                    /**设置任务目标下标*/
                    taskTarget.setTargetIndex(taskTargetList.size());
                    taskTargetList.add(taskTarget);
                }

                taskSet.setTaskTargetList(taskTargetList);
            }

        } catch (Exception e) {
            throw new RuntimeException(MessageFormat.format("出现异常任务id: {}, {}", taskSet.getId(), e.getMessage()), e);
        }
    }


    /**
     * 初始化任务前一任务
     *
     * @param taskMap
     */
    private void initPrevTask(Map<Integer, TaskSet> taskMap) {
        /**第1个任务没有前一任务，其他有前一任务*/
        TaskSet nextTask = null;
        for (Map.Entry<Integer, TaskSet> entry : taskMap.entrySet()) {
            nextTask = taskMap.get(entry.getValue().getNextId());
            /**最后一个任务，找不到下一任务*/
            if (nextTask == null) {
                continue;
            }
            nextTask.setPreviousId(entry.getValue().getId());
        }
    }

    /**
     * 生成talk与任务的映射Map，需要保证1个对话只会被1个任务用到
     */
    private Map<Integer, Integer> newTalkToTaskMap(List<TaskSet> list) {
        Map<Integer, Integer> talkToTaskMap = new HashMap<>(list.size());
        for (TaskSet taskSet : list) {
            int taskTargetCount = taskSet.getTaskTargetCount();
            for (int i = 0; i < taskTargetCount; i++) {
                TaskTarget taskTarget = taskSet.getTaskTargetByIndex(i);
                /**只匹配对话*/
                if (!isMatchTargetType(taskTarget, TaskTargetType.TALK)) {
                    continue;
                }

                List<Integer> talkList = ((TalkTargetParam) taskTarget.getTaskTargetParam()).getTalkList();
                for (int talkId : talkList) {
                    talkToTaskMap.put(talkId, taskSet.getId());
                }
            }
        }

        return talkToTaskMap;
    }

    private Map<TaskType, List<Integer>> newTaskTypeListMap(List<TaskSet> list) {
        Map<TaskType, List<Integer>> taskTypeListMap = new HashMap<>();
        for (TaskSet taskSet : list) {
            List<Integer> taskSetList = taskTypeListMap.get(taskSet.getTaskType());
            if (taskSetList == null) {
                taskSetList = new ArrayList<>();
                taskTypeListMap.put(taskSet.getTaskType(), taskSetList);
            }

            if (taskSet.getPreviousId() <= 0) {
                taskSetList.add(taskSet.getId());
            }
        }


        return taskTypeListMap;
    }

//    /**接取第一个主线任务，创建角色时需要接取*/
//    public void acceptFirstMainTask(Role role) {
//        TaskSet firstMainTask = getTaskSet(TaskDataPool.FIRST_MAIN_TASKID);
//        acceptTask(role, firstMainTask);
//    }

//    /***
//     * 接取任务
//     * @param role
//     * @param taskSet
//     */
//    public void acceptTask(Role role, TaskSet taskSet) {
//logger.error("接取任务：roleId : {}, 任务Id: {}" , role.getRoleId() ,taskSet.getId() );
//        //判断是否可以接取任务
//        if (!canAcceptTask(role, taskSet)) {
//            // TODO 是否需要 加上不能接取原因提示
//            logger.error("接取任务时不能接取 roleId : {}， 任务id {}", role.getRoleId(), taskSet.getId());
//            return ;
//        }
//
//        doAcceptTask(role, taskSet);
//
//        /**接取任务后需要更新任务显示*/
//        pushTasksOnLogin(role);
//    }

//    /**
//     * 执行接取任务逻辑(前面已经判断是否可以接取)
//     * @param role
//     * @param taskSet
//     */
//    public void doAcceptTask(Role role, TaskSet taskSet) {
//        RoleTask roleTask = role.getTask();
//        roleTask.acceptTask(taskSet.getId());
//
//        /**接取完后，执行任务目标相关的前置动作，比如刷新NPC*/
//        TaskTarget taskTarget = getRoleDoingTaskTarget(role, taskSet);
//        startTaskTarget(role, taskSet, taskTarget);
//    }

    /**
     * 开始任务目标，做些任务目标相关的前置动作，比如显示中间点NPC
     */
    public void startTaskTarget(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        /**有些任务没有任务目标，没有任务目标时返回*/
        if (taskTarget == null) {
            return;
        }

        triggerTaskTarget(role, taskSet, taskTarget);

        if (isMatchExecType(taskTarget, TaskTargetExecType.FLUSH_NODE_NPC)) {
            showNodeNpc(role, taskSet, taskTarget);
        }
    }

    /**
     * 显示中间点NPC
     */
    private void showNodeNpc(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        // TODO 暂时只显示接任务的玩家，其他玩家不显示
        List<Integer> list = (List<Integer>) taskTarget.getExecParam();
        for (Integer npcId : list) {
            SpringUtils.getBean(NewNpcService.class).showNodeNpc(role, npcId, false);
        }
    }

    /**
     * 隐藏中间点NPC
     */
    private void hideNodeNpc(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        List<Integer> list = (List<Integer>) taskTarget.getExecParam();
        for (Integer npcId : list) {
            SpringUtils.getBean(NewNpcService.class).hideNodeNpc(role, npcId, false);
        }
    }

    /**
     * 传送地图
     * @param role
     * @param taskSet
     * @param taskTarget
     */
    private void transferMap(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        List<Integer> list = (List<Integer>) taskTarget.getExecParam();
        SpringUtils.getMapService().changeMap(role, list.get(0), list.get(1), list.get(2));
    }


//    /**
//     * // TODO 需要加上判断逻辑
//     * 判断是否可以接取任务
//     * @param role
//     * @param taskSet
//     * @return
//     */
//    public boolean canAcceptTask(Role role, TaskSet taskSet) {
//        /**判断是否已经接取，已经接取当然就不能再接取了*/
//        if (isTaskAccepted(role, taskSet)) {
//            logger.error("任务已经接取，不能再接取，角色ID: {}, 任务ID: {}, 已接任务列表：{}, 任务数据：{}", role.getRoleId(), taskSet.getId(), Json.toJson(role.getTask().getAcceptedTaskList()), Json.toJson(role.getTask()));
//            return false;
//        }
//
//        /** 判断前一任务是否已经完成*/
//        //TODO 对于没有前一任务完成要求的后面再考虑
//        if (!isPrevTaskFinished(role, taskSet)) {
//            return false;
//        }
//logger.error("是否可以接取任务：roleId : {}, 任务Id: {}， 结果为true" , role.getRoleId() ,taskSet.getId() );
//
//        return true;
//    }

    /**
     * 任务是否已经接取
     */
    public boolean isTaskAccepted(Role role, TaskSet taskSet) {
        if (taskSet == null || role==null) {return false;}
        RoleTask roleTask = role.getTask();
        return roleTask.isAccepted(taskSet.getId());
    }

    /**
     * 前一任务是否已经完成
     *
     * @param role
     * @param taskSet
     * @return
     */
    public boolean isPrevTaskFinished(Role role, TaskSet taskSet) {
        TaskSet prevTask = getTaskSet(taskSet.getPreviousId(), role);
        /**可能不存在前一任务，比如主线第1个任务没有前一任务。此时返回为true*/
        if (prevTask == null) {
            return true;
        }

        RoleTask roleTask = role.getTask();
        return roleTask.isFinished(prevTask.getId());
    }

    @EventHandler(EventType.LOGIN)
    public void handleLoginEvent(LoginEvent loginEvent) {
        Role role = loginEvent.getRole();

        /**检测是否回退任务进度*/
        revertAcceptedTaskTarget(role);

        /**显示任务信息*/
        pushTasksOnLogin(role);
    }

    @EventHandler(EventType.LOGOUT)
    public void handleLogoutEvent(LogoutEvent logoutEvent) {
        Role role = logoutEvent.getRole();

        /**检测是否回退任务进度*/
        revertAcceptedTaskTarget(role);
    }


    /**
     * 处理进入地图事件
     */
    @EventHandler(EventType.ENTER_MAP)
    public void handleEnterMapEvent(EnterMapEvent enterMapEvent) {
        Role role = enterMapEvent.getRole();

        /**判断是否有进入地图弹出的对话，有则需要弹出*/
        ((TalkTargetHandler) TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.TALK)).popTalkOnEnterMap(role);

        /**放到线程后面执行，保证前面的NPC清空包先发给客户端，解决任务中间点NPC不显示问题*/
        ThreadLocalUtil.addLocalTask(role, ()->showNodeNpcOnEnterMap(role));
    }

    /**
     * 在进入地图时 显示中间点NPC
     */
    private void showNodeNpcOnEnterMap(Role role) {
        List<Integer> acceptedTaskList = role.getTask().getAcceptedTaskList();
        for (Integer taskId : acceptedTaskList) {
            TaskSet taskSet = getTaskSet(taskId, role);

            /**获得已接任务正在进行的任务目标*/
            TaskTarget doingTaskTarget = getRoleDoingTaskTarget(role, taskSet);
            /**任务目标都完成时，可能获得null*/
            if (doingTaskTarget == null) {
                continue;
            }

            if (!isMatchExecType(doingTaskTarget, TaskTargetExecType.FLUSH_NODE_NPC)) {
                continue;
            }

            showNodeNpc(role, taskSet, doingTaskTarget);
        }

    }

    /**
     * 是否匹配执行类型
     */
    private boolean isMatchExecType(TaskTarget taskTarget, TaskTargetExecType taskTargetExecType) {
        /**可能存在没有执行操作的*/
        if (taskTarget == null || taskTarget.getExecType() == null) {
            return false;
        }

        return taskTarget.getExecType().equals(taskTargetExecType);
    }

    /**
     * 把任务数据推送到客户端
     */
    public void pushTasksOnLogin(Role role) {
        ((SchoolTaskHandler) TaskHelper.INSTANCE.getTaskHandler(TaskType.SCHOOL)).pushGuideTask(role);//初始化师门任务
         roleService.scoreTask(role,role.getActivity().getRechargeScore());//初始化积分任务
        roleService.titleTask(role);//初始化称号任务
        roleService.mrljAddPolorTask(role);
        roleService.zhuanshengAddPolorTask(role);
        List<Integer> acceptedTaskList = role.getTask().getAcceptedTaskList();
        for (int taskId : acceptedTaskList) {
            TaskSet taskSet = getTaskSet(taskId, role);
            if (taskSet == null || taskSet.getTaskType() == null) {
                new RuntimeException("任务数据异常:" + taskId);
                continue;
            }

            // TODO 后面有时间再优化
            TaskHandler taskHandler = TaskHelper.INSTANCE.getTaskHandler(taskSet.getTaskType());
            if (taskHandler != null) {
                taskHandler.pushTask(role, taskSet);
            }
        }
    }

    /**
     * 当任务名称与下一任务名称不同时，需要发包告诉客户端，否则这个任务的信息会一直不会消失，除非重新登录
     */
    public void pushEndTask(Role role, String taskName) {
        RespTasksDel respTasksDel = getRespTasksDel(role, taskName);
        MessagePusher.pushMessage(role, respTasksDel);
    }

    public RespTasksDel getRespTasksDel(Role role, String taskName) {
        RespTasksDel respTasksDel = new RespTasksDel();
        respTasksDel.setList(new ArrayList<>());
        respTasksDel.getList().add(taskName);

        return respTasksDel;
    }

    public void pushTaskInfo(Role role, TaskInfo taskInfo) {
        if (taskInfo == null) {return ;}
        
        RespTasks respTasks = new RespTasks();
        ArrayList<TaskInfo> taskList = new ArrayList<>();
        respTasks.setList(taskList);
        taskList.add(taskInfo);
        MessagePusher.pushMessage(role, respTasks);
    }

    public TaskInfo getTaskInfo(Role role, TaskSet taskSet) {
        TaskInfo taskInfo = new TaskInfo();
        taskInfo.setQuit((short) taskSet.getGiveUp());// 是否可以放弃
        taskInfo.setTaskName(taskSet.getTaskName());
        taskInfo.setShow_name(taskSet.getTaskName());
        taskInfo.setTaskInfo(taskSet.getTaskJieshao());
        taskInfo.setTaskZhiyin(taskSet.getTaskZhiyin());
        taskInfo.setTaskJiangli(taskSet.getTaskGift());

        handleSpecialTaskInfo(role, taskSet, taskInfo);

        return taskInfo;
    }

    /**
     * 处理特殊任务的信息
     */
    public void handleSpecialTaskInfo(Role role, TaskSet taskSet, TaskInfo taskInfo) {
        if (taskSet.getId() == TaskDataPool.studySkillTaskId) {
            Map<String, Byte> autoAttrib = role.getExtendBox().getAutoAttrib();
            int chose = autoAttrib.getOrDefault("type", (byte) 0);
            taskInfo.setTaskInfo(taskInfo.getTaskInfo().replace("{skillName}", getLearnSkillName((byte) chose, role.getPolar())));
            taskInfo.setTaskZhiyin(taskInfo.getTaskZhiyin().replace("{skillName}", getLearnSkillName((byte) chose, role.getPolar())));
        }
    }

    public String getLearnSkillName(byte chose, short menpai) {
        String skillName;
        if (menpai == 1) {
            skillName = "金光乍现";
        } else if (menpai == 2) {
            skillName = "摘叶飞花";
        } else if (menpai == 3) {
            skillName = "滴水穿石";
        } else if (menpai == 4) {
            skillName = "举火焚天";
        } else {
            skillName = "落土飞岩";
        }

        if (chose == Const.ATTRIB_TYPE_PHYCIAL) {
            return "力破千钧";
        } else if (chose == Const.ATTRIB_TYPE_MAGIC) {
            return skillName;
        } else {
            return "力破千钧#n或#R" + skillName;
        }

    }

    /**
     * 是否匹配对应的任务目标类型
     */
    public boolean isMatchTargetType(TaskTarget taskTarget, TaskTargetType taskTargetType) {
        return taskTarget.getTaskTargetType().equals(taskTargetType);
    }

    /**
     * 是否能配置对应的弹出类型
     */
    public boolean isMatchPopType(TaskTarget taskTarget, TaskTargetPopType taskTargetPopType) {
        /**弹出类型可能为null*/
        if (taskTarget.getPopType() == null) {
            return false;
        }
        return taskTarget.getPopType().equals(taskTargetPopType);
    }

    /**
     * 处理对话结束事件
     */
    @EventHandler(EventType.TALK_END)
    public void handleTalkEndEvent(TalkEndEvent talkEndEvent) {
        /**判断结束那个对话对应哪个任务，并更新对应任务进度*/

        Role role = talkEndEvent.getRole();
        /**role不知道在什么情况 下会null，暂时先这样*/
        if (role == null) {
            return;
        }

        TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.TALK).handleEvent(role, talkEndEvent);
        /**检测是否需要发送指引*/
        pushGuide(role, Const.INSTRUCTION_TALK_END, talkEndEvent.getTalkId());

        /**宠物升级成功*/
        Message message = role.popTempCache("pet_fly_success");
        if (message != null) {
            MessagePusher.pushMessage(role, message);
        }
    }

    /**
     * 处理任务结束事件
     */
    @EventHandler(EventType.TASK_END)
    public void handleTaskEndEvent(TaskEndEvent taskEndEvent) {
        /**取数据库取出这个任务完成需要发的指引 可能有多个 不知道能不能连续发送 先看看*/
        Role role = taskEndEvent.getRole();
        /**检测是否需要发送指引*/
        pushGuide(role, Const.INSTRUCTION_TASK_END, taskEndEvent.getTaskId());

        if(taskEndEvent.getTaskId()==24){
            /**如果完成的任务ID是24 关掉人物的自动战斗*/
            role.setAutoFight((byte) 0);
            RespUpdate respUpdate = new RespUpdate();
            respUpdate.setRoleId(role.getRoleId());
            respUpdate.setList(Collections.singletonList(new FiedValue(307, role.getAutoFight())));
            MessagePusher.pushMessage(role, respUpdate);
        }
    }

    /**
     * 检测是否需要发送指引
     */
    private void pushGuide(Role role, byte guideType, int req) {
        Set<Instruction> instructions = getInstruction(guideType, req);
        if (Objects.isNull(instructions)) {
            return;
        }
        for (Instruction instruction : instructions) {
            /**力法选择这个先这样处理吧*/
            if (instruction.getInstructionId() == 43 && role.getExtendBox().getAutoAttrib().getOrDefault("type", (byte) 0) != 1) {
                continue;
            } else if (instruction.getInstructionId() == 42 && role.getExtendBox().getAutoAttrib().getOrDefault("type", (byte) 0) != 2) {
                continue;
            }
            pushGuide(role, instruction.getInstructionId());
        }
    }


    /**
     * 根据类型取出需要的指引 可能为多个
     */
    private Set<Instruction> getInstruction(byte type, int req) {
        Map<Integer, Set<Instruction>> reqSetMap = TaskDataPool.typeToInstruction.get(type);
        if (reqSetMap == null || reqSetMap.size() <= 0) {
            return null;
        }
        return reqSetMap.get(req);
    }

    /**
     * 获得下一个任务目标
     *
     * @param taskSet
     * @param taskTarget
     * @return
     */
    private TaskTarget getNextTaskTarget(TaskSet taskSet, TaskTarget taskTarget) {
        int targetIndex = taskTarget.getTargetIndex();
        int nextTargetIndex = targetIndex + 1;
        return taskSet.getTaskTargetByIndex(nextTargetIndex);
    }

//    /**
//     * 提交任务
//     * @param role
//     * @param taskSet
//     */
//    private void submitTask(Role role, TaskSet taskSet) {
//logger.trace("提交任务: {}", taskSet.getId());
//        // TODO 需要实现逻辑
//        /**给玩家任务奖励，再标记已经完成*/
//        giveAward(role, taskSet);
//
//        RoleTask roleTask = role.getTask();
//        roleTask.updateToFinished(taskSet.getId());
//
//        /**发隐藏包*/
//        pushEndTask(role, taskSet);
//
//        /**接取下一任务*/
//        TaskSet nextTask = getNextTask(taskSet);
//        if (nextTask != null) {
//logger.trace("接取下一任务: {}", nextTask.getId());
//            acceptTask(role, nextTask);
//        }
//    }

    /**
     * 获得下一任务
     */
    public TaskSet getNextTask(TaskSet taskSet, Role role) {
        return getTaskSet(taskSet.getNextId(), role);
    }

    /**
     * 给玩家任务奖励
     *
     * @param role
     * @param taskSet
     */
    public void giveAward(Role role, TaskSet taskSet) {
        // TODO 从之前代码拷贝过来的，需要后续查看怎么优化
        RoleService roleService = SpringUtils.getBean(RoleService.class);
        EquipService equipService = SpringUtils.getBean(EquipService.class);
        int petId = role.getPetBox().getFightPetId();
        NutMap nutMap = taskSet.getRewardList();
        for (Map.Entry<String, Object> entry : nutMap.entrySet()) {
            String key = entry.getKey();
            if (key.equals("exp")) {
                int exp = nutMap.getInt(key);
                /**经验是否需要乘等级*/
                boolean isExpMultiplyLevel = nutMap.getBoolean("expMultiplyLevel", false);
                if (isExpMultiplyLevel) {
                    exp *= role.getLevel();
                }

                roleService.addExp(role, (int) exp, 1, petId);
            } else if (key.equals("item")) {
                NutMap itemV = nutMap.getAs(key, NutMap.class);
                /**遍历列表添加物品*/
                List<NutMap> list = itemV.getAsList("list", NutMap.class);
                for (NutMap itemEl : list) {
                    String name = itemEl.getAs("name", String.class);
                    int count = itemEl.getInt("count");
                    equipService.addMall(name, true, role, count);
                }
            } else if (key.equals("equip")) {
                List<NutMap> list = nutMap.getAsList(key, NutMap.class);
                for (NutMap equipEl : list) {
                    /**支持添加多个装备*/
                    List<String> nameList = equipEl.getAsList("nameList", String.class);
                    int count = equipEl.getInt("count");
                    /**这个列表中的添加的数量都是一样的*/
                    List<Equip> equipSetList = new ArrayList<Equip>();
                    for (String name : nameList) {
                        Equip equipSet = EquipDataPool.getByName(name);
                        equipSetList.add(equipSet);
                    }
                    equipService.addEquipMatchRole(role, equipSetList, count, true);
                }

            } else if (key.equals("pot")) {//潜能
                roleService.addPot(role, (int) entry.getValue());
            } else if (key.equals("cash")) {//代金券
                int cash = (int) entry.getValue();
                int voucher = role.getVoucher();
                String tips = AsktaoUtil.getMoneyFormat(cash) + "文代金券";
                roleService.addRewardTips(role, tips, false);
                MessagePusher.pushMessage(role, new RespNotifyMisc("你获得了" + tips+"。"));
                role.setVoucher(voucher + cash);
                roleService.updateRoleMoney(role);
                RespIconCartoon respIconCartoon = new RespIconCartoon();
                respIconCartoon.setType((short) 3);
                respIconCartoon.setName("代金券");
                respIconCartoon.setParam(String.valueOf(cash));
                MessagePusher.pushMessage(role, respIconCartoon);
            } else if (key.equals("title")) {//称号
                NutMap titleV = nutMap.getAs(key, NutMap.class);
                String type = titleV.getString("type");
                String title = SpringUtils.getBean(SchoolService.class).replaceSchoolDesc((byte) role.getPolar(), titleV.getString("name"));
                SpringUtils.getRoleService().addTitle(role, new TitleInfo(type, title));
            } else if (key.equals("tao")) {//道行
                roleService.addTao(role, (int) entry.getValue());
                roleService.sendExtraAttribute(role);
            } else if (key.equals("matiral")) {//武学
                Pet pet = SpringUtils.getPetService().getPetById(petId, role);
                roleService.addPetMatiral(role, pet, (int) entry.getValue());
            } else if (key.equals("party_contrib")) {//帮贡
                roleService.addPartyContrib(role, (int) entry.getValue());
            } else if (key.equals("party_vitality")) {//帮派活力
                roleService.addPartyVitality(role, (int) entry.getValue());
            } else if (key.equals("party_construction")) {//帮派建设度
                roleService.addPartyConstruction(role, (int) entry.getValue());
            } else if (key.equals("party_capital")) {//帮派资金
                roleService.addPartyCapital(role, (int) entry.getValue());
            } else if (key.equals("dropgroup")) {//掉落
                SpringUtils.getDropService().drop(role, (int) entry.getValue());
            }
        }

    }

    /**
     * 发引导数据包给客户端
     */
    public void pushGuide(Role role, short guildType) {
        RespPlayInstruction playInstruction = new RespPlayInstruction();
        playInstruction.setType(guildType);
        MessagePusher.pushMessage(role, playInstruction);
//        logger.warn("发送引导数据到客户湍：roleId : {} , info: {}", role.getRoleId(), Json.toJson(playInstruction));
    }


    /**
     * 通过对话获得对应任务
     */
    public Integer getTaskByTalk(int talkId) {
        return TaskDataPool.talkToTaskMap.get(talkId);
    }


    /**
     * 获得角色在该npc上所有已接任务
     */
    public List<TaskSet> getAcceptedTaskListByNpc(Role role, NPC npc) {
        RoleTask roleTask = role.getTask();
        List<Integer> acceptedTaskList = roleTask.getAcceptedTaskList();
        List<TaskSet> taskSets = new ArrayList<TaskSet>(acceptedTaskList.size());

        SchoolService schoolService = SpringUtils.getBean(SchoolService.class);
        for (int taskId : acceptedTaskList) {
            TaskSet taskSet = getTaskSet(taskId, role);
            /**理论上不可能为空*/
            if (taskSet == null) {
                continue;
            }

            String taskNpcName = taskSet.getNpcName();
            logger.trace("任务ID {}， npcName {}, taskNpcName {}", taskSet.getId(), npc.getName(), taskNpcName);

            if (!npc.getName().contains(taskNpcName)) {
                continue;
            }

            taskSets.add(taskSet);
        }

        return taskSets;
    }

    /**
     * 获得NPC内容和按钮
     */
    public String getNpcContent(Role role, NPC npc) {
        String taskContent = getTaskContent(role, npc);
        if (taskContent != null) {
            return taskContent;
        }

        return appendTaskButton(role, npc);
    }

    /**
     * 获得任务独占的NPC内容和按钮
     */
    public String getTaskContent(Role role, NPC npc) {
        List<TaskSet> acceptedTaskList = getAcceptedTaskListByNpc(role, npc);
        for (TaskSet taskSet : acceptedTaskList) {
            if (taskSet.getTaskType() == TaskType.XIU_XING || taskSet.getTaskType() == TaskType.SHI_JUE_ZHEN) {
                return taskSet.getButtton();
            }

            if (taskSet.getId() == HelpPeopleTaskHandler.HELP_PEOPLE_END_TASKID) {
                return taskSet.getButtton();
            }
        }

        return null;
    }

    /***
     * 没有任务但达到条件时，给NPC添加按钮
     * @param role
     * @param npc
     * @return
     */
    public String getTaskButtons(Role role, NPC npc) {
        /**获得玩家对应npc上的所有已接任务*/
        List<TaskSet> acceptedTaskList = getAcceptedTaskListByNpc(role, npc);
        String buttons = getButtonContents(role, acceptedTaskList);

        /**获得师门任务接取按钮*/
        buttons += TaskHelper.INSTANCE.getTaskHandler(TaskType.SCHOOL).getTaskButtons(role, npc);
        /**获得阵营指引任务按钮*/
//        buttons += TaskHelper.INSTANCE.getTaskHandler(TaskType.CAMP_GUIDE).getTaskButtons(role, npc);

        return buttons;
    }

    /**获得所有任务中的button内容并加到npc的content的button之前*/
    private String appendTaskButton(Role role, NPC npc) {
        /**获得所有任务中的button*/
        String taskButtons = getTaskButtons(role, npc);


        Pattern pattern = Pattern.compile("\\[.+\\]");
        Matcher matcher = pattern.matcher(npc.getContent());
        StringBuffer sb = new StringBuffer();
        if (matcher.find()) {
            matcher.appendReplacement(sb, taskButtons + matcher.group());
            matcher.appendTail(sb);
        } else {
            sb.append(npc.getContent()).append(taskButtons);
        }

        return sb.toString();
    }

    /**
     * 获得任务列表中的button并拼接起来，返回内容不能是null
     */
    public String getButtonContents(Role role, List<TaskSet> taskSetList) {
        /**不存在时返回空字符串*/
        if (taskSetList == null || taskSetList.size() == 0) {
            return "";
        }

        StringBuffer buttonContents = new StringBuffer();

        for (TaskSet taskSet : taskSetList) {
            /**有些任务不在npc中显示按钮*/
            if (taskSet.getButtton() == null) {
                continue;
            }

            String button = taskSet.getButtton().trim();
            if (!Objects.isNull(TaskButtonHideHelper.INSTANCE.getTaskHandler(taskSet.getId()))) {
                button = TaskButtonHideHelper.INSTANCE.getTaskHandler(taskSet.getId()).getButtonContents(role, button);
            }
            buttonContents.append(button.trim());
        }
        return buttonContents.toString();
    }


    /**
     * 获得角色对应任务正在进行的任务目标
     */
    public TaskTarget getRoleDoingTaskTarget(Role role, TaskSet taskSet) {
        RoleTask roleTask = role.getTask();
        if(taskSet == null){
            return null;
        }
        /**任务还没有接时，返回null*/
        if (!roleTask.isAccepted(taskSet.getId())) {
            return null;
        }

        int targetProgressIndex = roleTask.getTargetProgress(taskSet.getId());
        return taskSet.getTaskTargetByIndex(targetProgressIndex);
    }

    /**
     * 处理穿戴装备事件
     */
    @EventHandler(EventType.ON_EQUIP)
    public void handleOnEquipEvent(OnEquipEvent onEquipEvent) {
        logger.trace("收到穿戴装备的事件，uid: {}, equip: {}", onEquipEvent.getPlayerUid(), onEquipEvent.getEquipName());
        /**判断对应的装备是否有已接取任务目标，有则更新任务状态*/
        Role role = onEquipEvent.getRole();
        /**role不知道在什么情况 下会null，暂时先这样*/
        if (role == null) {
            return;
        }
        SpringUtils.getBean(SendAchieve.class).handleOnEquipAchieveEvent(onEquipEvent);

        TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.ON_EQUIP).handleEvent(role, onEquipEvent);
    }

    /**
     * 更新任务进度，同时会触发之后逻辑
     */
    public void updateTargetProgress(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        TeamService teamService = SpringUtils.getTeamService();
        if (teamService.isInTeam(role)) {
            /**组队中*/
            if (teamService.isTeamLeader(role)) {
                if (taskSet.isTeamAccept()) {
                    /**队长时，同时帮队员触发*/
                    teamService.memberHandleThreadLocal(role, memberRole -> {
                        TaskTarget doingTaskTarget = getRoleDoingTaskTarget(memberRole, taskSet);
                        if (doingTaskTarget != null && doingTaskTarget.getTargetIndex() == taskTarget.getTargetIndex()) {
                            updateSingleTargetProgress(memberRole, taskSet, taskTarget);
                        }
                    });
                } else {
                    updateSingleTargetProgress(role, taskSet, taskTarget);
                }
            }
        } else {
            /**未组队中*/
            updateSingleTargetProgress(role, taskSet, taskTarget);
        }
    }

    private void updateSingleTargetProgress(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        RoleTask roleTask = role.getTask();
        /**更新任务进度之前先确认任务是已经接取的*/
        if (!roleTask.isAccepted(taskSet.getId())) {
            return;
        }
        roleTask.updateTargetProgress(taskSet.getId(), taskTarget.getTargetIndex(), taskSet.getTaskTargetCount());
        logger.trace("更新任务进度：任务目标下标: {}, 目标总数：{}", taskTarget.getTargetIndex(), taskSet.getTaskTargetCount());


        endTaskTarget(role, taskSet, taskTarget);
        triggerTask(role, taskSet, taskTarget);
    }

    /**
     * 完成任务目标，做些任务目标相关的后置动作，比如隐藏中间点NPC
     */
    private void endTaskTarget(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        if (isMatchExecType(taskTarget, TaskTargetExecType.FLUSH_NODE_NPC)) {
            hideNodeNpc(role, taskSet, taskTarget);
        } else if (isMatchExecType(taskTarget, TaskTargetExecType.ACCEPT_SCHOOL_TASK)) {
            ((SchoolTaskHandler) TaskHelper.INSTANCE.getTaskHandler(TaskType.SCHOOL)).acceptTask(role);
        } else if (isMatchExecType(taskTarget, TaskTargetExecType.TRANSFER_MAP)) {
            transferMap(role, taskSet, taskTarget);
        }
    }



    /**
     * 检测任务是否需要触发对应逻辑
     */
    private void triggerTask(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        /**触发对应的逻辑*/
        if (role.getTask().isCanSubmit(taskSet.getId())) {
            logger.trace("可以提交任务: {}", taskSet.getId());
            /**可以提交时，自动提交任务*/
            // TODO 会不会存在有些任务不是自动提交的？？
            TaskHelper.INSTANCE.getTaskHandler(taskSet.getTaskType()).submitTask(role, taskSet);
        } else {
            TaskTarget nextTarget = getNextTaskTarget(taskSet, taskTarget);
            logger.trace("下一目标: {}", Json.toJson(nextTarget));
            /**下一个目标可以立即触发时，进行触发操作*/
            triggerTaskTarget(role, taskSet, nextTarget);
        }
    }

    /**
     * 判断目标是否为符合触发条件，符合时触发
     */
    private void triggerTaskTarget(Role role, TaskSet taskSet, TaskTarget taskTarget) {
        if (isTriggerNow(role, taskSet, taskTarget, TaskTargetPopType.NOW)) {
//            LoggerFunction.TASK.getLogger().warn("{}({}) 任务id: {}, 触发任务目标开始", role.getUid(), role.getName(), taskSet.getId());
            TaskTargetHelper.INSTANCE.getTargetHandler(taskTarget.getTaskTargetType()).triggerNow(role, taskSet, taskTarget);
//            LoggerFunction.TASK.getLogger().warn("{}({}) 任务id: {}, 触发任务目标开始", role.getUid(), role.getName(), taskSet.getId());
        }
    }


    /**
     * 获得匹配任务目标类型的所有已接任务
     */
    public List<TaskSet> getAcceptedTasksMatchTarget(Role role, TaskTargetType taskTargetType) {
        List<Integer> acceptedTaskList = role.getTask().getAcceptedTaskList();
        List<TaskSet> matchTaskList = new ArrayList<TaskSet>(acceptedTaskList.size());
        for (Integer taskId : acceptedTaskList) {
            TaskSet taskSet = getTaskSet(taskId, role);
            if(taskSet == null ){
                continue;
            }
            /**获得已接任务正在进行的任务目标*/
            TaskTarget doingTaskTarget = getRoleDoingTaskTarget(role, taskSet);
            /**任务目标都完成时，可能获得null*/
            if (doingTaskTarget == null) {
                continue;
            }
            /**任务目标类型匹配*/
            if (!doingTaskTarget.getTaskTargetType().equals(taskTargetType)) {
                continue;
            }

            matchTaskList.add(taskSet);
        }

        return matchTaskList;
    }

    /**
     * 处理领取事件
     */
    @EventHandler(EventType.FETCH)
    public void handleFetchEvent(FetchEvent fetchEvent) {
        logger.trace("收到领取事件 uid : {}", fetchEvent.getPlayerUid());

        Role role = fetchEvent.getRole();
        /**role不知道在什么情况 下会null，暂时先这样*/
        if (role == null) {
            return;
        }


        /**判断不同的领取类型处理*/
        if (fetchEvent.getFetchType() == FetchEvent.FETCH_PET) {
            TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.FETCH_PET).handleEvent(role, fetchEvent);
        }

    }

    /**
     * 处理战斗结束事件
     */
    @EventHandler(EventType.FIGHT_END)
    public void handleFightEndEvent(FightEndEvent fightEndEvent) {
        ThreadLocalUtil.addLocalTask(fightEndEvent.getRole(), () -> doFightEnd(fightEndEvent.getRole(), fightEndEvent));

    }

    private void doFightEnd(Role role, FightEndEvent fightEndEvent) {
        /**在组队又不是队长时返回*/
        TeamService teamService = SpringUtils.getTeamService();
        if (teamService.isInTeam(role) && !teamService.isTeamLeader(role)) {
            return;
        }

        Integer taskId = role.getTask().getTaskIdByFightId(fightEndEvent.getFightId());
        /**如果任务ID找不到，则说明该战斗并非由任务触发，不处理*/
        if (taskId == null) {
            return;
        }

        TaskSet taskSet = getTaskSet(taskId, role);
        TaskHandler taskHandler = TaskHelper.INSTANCE.getTaskHandler(taskSet.getTaskType());
        if (taskHandler != null) {
            taskHandler.doFightEnd(role, fightEndEvent);
        }
    }

    /**
     * 还原战斗任务目标
     */
    public void revertFightTaskTarget(Role role, FightEndEvent fightEndEvent) {
        TaskSet fightTaskSet = getFightTaskSet(role, fightEndEvent.getFightId());
        revertTaskTarget(role, fightTaskSet);
    }

    /**
     * 获得战斗id对应的任务，如果不是任务触发战斗，则返回null
     */
    private TaskSet getFightTaskSet(Role role, int fightId) {
        RoleTask roleTask = role.getTask();
        Integer taskId = roleTask.getTaskIdByFightId(fightId);
        /**如果任务ID找不到，则说明该战斗并非由任务触发*/
        if (taskId == null) {
            return null;
        }

        return getTaskSet(taskId, role);
    }

    /**
     * 对已经接取的任务目标进行检测，如果需要回退进度进行回退
     */
    private void revertAcceptedTaskTarget(Role role) {
        List<Integer> acceptedTaskList = role.getTask().getAcceptedTaskList();
        for (Integer taskId : acceptedTaskList) {
            revertTaskTarget(role, getTaskSet(taskId, role));
        }

    }

    /**
     * 对应任务进度中正在做的目标的PopType是NOW时，还原到不是NOW的的目标
     */
    private void revertTaskTarget(Role role, TaskSet taskSet) {
        if (taskSet == null) {
            return;
        }

        TaskTarget roleDoingTaskTarget = getRoleDoingTaskTarget(role, taskSet);
        if (roleDoingTaskTarget == null) {
            return;
        }

        if (isMatchPopType(roleDoingTaskTarget, TaskTargetPopType.NOW)) {
            int targetIndex = roleDoingTaskTarget.getTargetIndex();
            for (int index = targetIndex - 1; index >= 0; index--) {
                TaskTarget prevTaskTarget = taskSet.getTaskTargetByIndex(index);
                if (!isMatchPopType(prevTaskTarget, TaskTargetPopType.NOW)) {
                    role.getTask().revertTargetProgress(taskSet.getId(), prevTaskTarget.getTargetIndex());
                    startTaskTarget(role, taskSet, prevTaskTarget);
                }
            }
        }
    }

    /**
     * 处理移动事件
     */
    @EventHandler(EventType.MOVE)
    public void handleMoveEvent(MoveEvent moveEvent) {

        Role role = moveEvent.getRole();
        /**role不知道在什么情况 下会null，暂时先这样*/
        if (role == null) {
            return;
        }
//logger.trace("收到移动事件 uid : {}, 位置：{}", moveEvent.getPlayerUid(), Json.toJson(role.getPosition()));

        /**判断是否有行走到指定位置触发对话，有则触发*/
        List<Integer> acceptedTaskList = role.getTask().getAcceptedTaskList();
        for (int taskId : acceptedTaskList) {
            TaskSet taskSet = getTaskSet(taskId, role);
            if (taskSet == null) {
                continue;
            }
            if (SpringUtils.getBean(DigTreasureTaskHandler.class).checkStartDig(role, taskSet)) {
                /**挖宝时，则不触发其他任务*/
                break;
            }

            TaskTarget taskTarget = getRoleDoingTaskTarget(role, taskSet);
            /**任务目标都完成时，可能获得null*/
            if (taskTarget == null) {
                continue;
            }

            /**是否可以现在触发*/
            if (!isTriggerNow(role, taskSet, taskTarget, TaskTargetPopType.WALK_TO)) {
                continue;
            }

            TaskTargetHelper.INSTANCE.getTargetHandler(taskTarget.getTaskTargetType()).triggerNow(role, taskSet, taskTarget);

            /**触发一个，就不需要再检测其他的了*/
            break;
        }
    }

    /**
     * 现在是否可以触发
     */
    public boolean isTriggerNow(Role role, TaskSet taskSet, TaskTarget taskTarget, TaskTargetPopType taskTargetPopType) {
        /**玩家正在对话或者战斗过程中不能触发*/
        if (role.getTalk().isInTalk() || SpringUtils.getFightService().isInFight(role)) {
         //   LoggerFunction.TASK.getLogger().warn("{}({})不能触发下一任务目标,  任务id:{}, 目标类型：{}, 在对话:{}, 在战斗:{}", role.getUid(), role.getName(), taskSet.getId(), taskTarget.getTaskTargetType(), role.getTalk().isInTalk(), SpringUtils.getFightService().isInFight(role));
            return false;
        }

        /**只处理指定类型的*/
        if (TaskTargetPopType.WALK_TO.equals(taskTargetPopType)) {
            if (isMatchPopType(taskTarget, taskTargetPopType)) {
                /**不匹配地图位置时，跳过*/
                NutMap nutMap = (NutMap) taskTarget.getPopParam();
                MapService mapService = SpringUtils.getBean(MapService.class);
                if (mapService.isInPosition(role, nutMap.getInt("mapId"), (short) nutMap.getInt("x"), (short) nutMap.getInt("y"), Const.MONSTER_PERIMETER)) {
                    return true;
                }
            }
        } else if (TaskTargetPopType.NOW.equals(taskTargetPopType)) {
            if (isMatchPopType(taskTarget, taskTargetPopType)) {
                return true;
            }
        }

        return false;
    }

    public TalkSet getTalkMatchNpc(Role role, TaskSet taskSet, NPC npc) {
        return ((TalkTargetHandler) TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.TALK)).getTalkMatchNpc(role, taskSet, npc);
    }

    @EventHandler(EventType.CONFIRM)
    public void handleConfirmEvent(ConfirmEvent confirmEvent) {
        Role role = confirmEvent.getRole();
        if (role == null) {
            return;
        }

        TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.STUDY).handleEvent(role, confirmEvent);
    }

    @EventHandler(EventType.STUDY_SKILL)
    public void handleStudySkillEvent(StudySkillEvent studySkillEvent) {
        /**判断学习的技能是否为已接任务的目标，是则更新目标*/
        Role role = studySkillEvent.getRole();
        if (role == null) {
            return;
        }
        SpringUtils.getBean(SendAchieve.class).achieveSkillLevelEvent(studySkillEvent);
        TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.STUDY_SKILL).handleEvent(role, studySkillEvent);
    }

    /**
     * 处理召唤守护事件
     */
    @EventHandler(EventType.CALL_GUARD)
    public void handleCallGuardEvent(CallGuardEvent callGuardEvent) {
        Role role = callGuardEvent.getRole();
        if (role == null) {
            return;
        }

        TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.CALL_GUARD).handleEvent(role, callGuardEvent);
    }

    /**
     * 处理角色升级事件
     */
    @EventHandler(EventType.ROLE_LEVEL_UP)
    public void handleRoleLevelUpEvent(RoleLevelUpEvent roleLevelUpEvent) {
        Role role = roleLevelUpEvent.getRole();
        if (role == null) {
            return;
        }

        TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.ROLE_LEVEL_UP).handleEvent(role, roleLevelUpEvent);

        /**检测是否需要发送指引*/
        pushGuide(role, Const.INSTRUCTION_LEVEL_UP, roleLevelUpEvent.getLevel());
    }

    /**
     * 获得匹配指定任务类型的已接任务列表
     */
    public List<TaskSet> getAcceptedTaskListMatchTaskType(Role role, TaskType taskType) {
        List<Integer> acceptedTaskList = null;
        try {
            acceptedTaskList = role.getTask().getAcceptedTaskList();
        } catch (ConcurrentModificationException e) {
         //   LoggerUtils.error("{}({}),taskType:{},sessionId:{}", role.getUid(), role.getName(), taskType, e.getMessage(), e);
        }
        //List<Integer> acceptedTaskList = role.getTask().getAcceptedTaskList();
        if (acceptedTaskList != null) {
            List<TaskSet> taskList = new ArrayList<>(acceptedTaskList.size());

            for (Integer taskId : acceptedTaskList) {
                TaskSet taskSet = getTaskSet(taskId, role);
                if (!isMatchTaskType(taskSet, taskType)) {
                    continue;
                }

                taskList.add(taskSet);
            }
            return taskList;
        }

        return Collections.emptyList();
    }

    public boolean isMatchTaskType(TaskSet taskSet, TaskType taskType) {
        if (taskSet == null || taskSet.getTaskType() == null) {
            return false;
        }
        if (!taskSet.getTaskType().equals(taskType)) {
            return false;
        }
        return true;
    }

    /**
     * 获得指定任务类型的每组任务的第1个任务的集合
     */
    public List<Integer> getTaskListByType(TaskType taskType) {
        return TaskDataPool.taskListByType.get(taskType);
    }

    /**
     * 请求放弃任务
     *
     * @param role
     * @param taskName
     */
    public void requestGiveUpTask(Role role, String taskName) {
        // TODO 暂时写死判断提示，后续需要优化
        if (taskName.startsWith("sm")) {
            ((SchoolTaskHandler) TaskHelper.INSTANCE.getTaskHandler(TaskType.SCHOOL)).giveUpTask(role);
            return;
        }
        if (taskName.startsWith("助人为乐")) {
            SpringUtils.getBean(HelpPeopleTaskHandler.class).giveUpTask(role);
            return;
        }

        if (taskName.startsWith("通天塔")) {
            SpringUtils.getBean(TowerTaskHandler.class).requestGiveUpTask(role);
            return;
        }

        if (taskName.startsWith("宠物飞升")) {
            SpringUtils.getBean(PetFlyTaskHandler.class).giveUpTask(role);
            return;
        }

        String msg = "是否确认放弃#R" + taskName + "#n任务？";
        role.setConfirm(new GiveUpTaskConfirm(taskName));
        RespConfirm respConfirm = new RespConfirm();
        respConfirm.setTips(msg);
        MessagePusher.pushMessage(role, respConfirm);
    }

    /**
     * 处理采集事件
     */
    @EventHandler(EventType.GATHER_END)
    public void handleCollectEvent(GatherEndEvent gatherEndEvent) {
        Role role = gatherEndEvent.getRole();
        if (role == null) {
            return;
        }

        switch (role.getGatherType()) {
            case Const.GATHER_TYPE_PLANT:
                TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.GATHER).handleEvent(role, gatherEndEvent);
                break;
            case Const.GATHER_TYPE_TREASURE:
                SpringUtils.getBean(DigTreasureTaskHandler.class).endDig(role);
                break;
            default:
                TaskTargetHelper.INSTANCE.getTargetHandler(TaskTargetType.GATHER).handleEvent(role, gatherEndEvent);
        }
    }

    /**
     * 每日任务重置
     */
    public void dailyResetTask(Role role) {
        List<Integer> acceptedTaskList = role.getTask().getAcceptedTaskList();
        TaskSet taskSet = null;
        for (Integer taskId : acceptedTaskList) {
            try{
                taskSet = getTaskSet(taskId, role);
                if (taskSet == null) {
                    /**任务数据都拿不到，是不是说明这个任务数据有问题？直接先删除了*/
                    role.getTask().deleteTask(taskId);
                }

                /**进行任务重置*/
                TaskHandler taskHandler = TaskHelper.INSTANCE.getTaskHandler(taskSet.getTaskType());
                if (taskHandler != null) {
                    taskHandler.resetTask(role, taskSet);
                }
            }catch(Exception e){

            }

        }
    }

    /**
     * 根据NPC名字找到助人为乐任务
     */
    public TaskSet getHelpTaskByNpcName(Role role, String npcName) {
        Integer taskId = TaskDataPool.helpTaskByName.get(npcName);
        if (taskId == null) {
            return null;
        }

        return getTaskSet(taskId, role);
    }

    /**根据任务名拿到玩家已接对应任务的TaskInfo*/
    public TaskInfo getTaskInfoByName(Role role, String taskName) {
        List<Integer> acceptedTaskList = role.getTask().getAcceptedTaskList();
        if (acceptedTaskList == null || acceptedTaskList.size() == 0) {
            return null;
        }
        TaskSet taskSet = null;
        for (int taskId : acceptedTaskList) {
            taskSet = getTaskSet(taskId, role);
            if (taskSet == null) {continue;}
            if (taskSet.getTaskName().equals(taskName)) {
                Class clazz = TaskDataPool.type2Handler.get(taskSet.getTaskType());
                Object instance = SpringUtils.getBean(clazz);
                if (instance instanceof TaskHandler) {
                    return ((TaskHandler)instance).getTaskInfo(role, taskSet);
                }
                if (instance instanceof TaskActivityHandler) {
                    return ((TaskActivityHandler)instance).getTaskInfo(role, taskSet);
                }
            }
        }

        return null;
    }
}
